#include <inttypes.h>

#define GRAY_IMPLEMENTATION
#include "gray.h"

static void prefix_function(void);
static void postfix_function(void);

#define TEST_INIT prefix_function()
#define TEST_FINI postfix_function()
#include "acutest.h"

#ifndef UNUSED
#define UNUSED(X) ((void)X)
#endif

static const uint_t byte_mask = (uint_t)((1u << CHAR_BIT) - 1u);
static uint_t max = 0, step = 0, step_variance = 0;

void prefix_function(void)
{
    srand((unsigned)time(NULL));
    max = 0;
    for (size_t i = 0; i < sizeof(max); i++)
    {
        max = (uint_t)((max << CHAR_BIT) | byte_mask);
    }
    step = max / 10000u ? max / 10000u : 1u;
    step_variance = step / 100u ? step / 100u : 1u;
}

void postfix_function(void)
{
}

void test_random_spread(void)
{

    for (uint_t i = 0;
         i < max - step - step_variance;
         i += step_variance + (uint_t)(((uint64_t)rand() * (uint64_t)rand()) % step_variance))
    {
        gray_t g = uint_to_gray(i);
        uint_t u = gray_to_uint(g);
        TEST_CHECK(i == u);
        TEST_MSG("i = 0x%016lx\ng = 0x%016lx\nu=%016lx", i, g, u);
    }
}

TEST_LIST =
{
    { "random spread of values", test_random_spread },

    { NULL, NULL },
};
